<?php

include_once 'sc2parser.php';
include_once 'database.php';


class sc2dataManager
{
	private static
		$tableOf = array (
			'account' => 'sc2_accounts',
			'portrait' => 'sc2_portraits',
			'clan' => 'sc2_clans',
			'1v1' => 'sc2_1v1_leagues',
			'race' => 'sc2_races',
			'league' => 'sc2_leagues',
			'realm' => 'sc2_realms',
			'expansion' => 'sc2_expansions',
			),
		$indexOf = null;


	public static function init () {

		self::load_indexes();
	}


	// Store all database indexes to $indexOf.
	private static function load_indexes () {

		$db = Database::connect();

		self::fill_indexes($db, 'race');
		self::fill_indexes($db, 'league');
		self::fill_indexes($db, 'realm');
		self::fill_indexes($db, 'expansion');
		self::fill_indexes($db, 'clan');
		self::fill_indexes($db, 'account');
	}

	private static function fill_indexes (&$db, $fieldName) {
		$dest =  &self::$indexOf[$fieldName];
		$table = self::$tableOf[$fieldName];
		self::get_database_indexes($db, $dest, $table);
		$dest[null] = null;
	}

	private static function get_database_indexes (&$db, &$dest, $table) {

		$query = "SELECT * FROM $table";
		$r = $db->query($query)->fetch_all();

		foreach ($r as $value) {
			$dest[$value[1]] = $value[0];
		}
	}


	public function __construct () {
		$this->db = Database::connect();
	}


	// Get all player's URL.
	public function load_urls () {

		static $query = "SELECT user_id, pf_cuentas FROM ygd_profiles_data WHERE pf_cuentas IS NOT NULL";
		static $pattern = "#http://(.*?)\.battle.net/sc2#";

		$answer = $this->db->query($query);
		$answer = $answer->fetch_all();

		$result = array();

		foreach ($answer as $row) {
			$urls = preg_split("#[\n\s]+#",$row[1]);
			foreach ($urls as $url) {
				$r = &$result[];
				$r['profile']['id'] = $this->get_account_id($url);
				$p = &$r['profile']['account'];
				preg_match($pattern, $url, $realm);
				$p['user_id'] = $row[0];
				$p['url'] = $url;
				$p['realm'] = self::$indexOf['realm'][$realm[1]];
			}
		}

		return $result;
	}

	// Parse all profiles_found.
	public function parse_profiles () {

		$multi_curl = curl_multi_init();
		$profileList = $this->load_urls();
		$sc2parser = new sc2parser();

		// Preparing for download all HTML codes.
		foreach ($profileList as &$item) {
			$ladderURL = $item['profile']['account']['url']
				. 'ladder/leagues#current-rank';
			$ch = &$item['curl'];
			$ch = curl_init($ladderURL);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_multi_add_handle($multi_curl, $ch);
		}

		// Downloading all HTML codes.
		$running = null;
		do {
			curl_multi_exec($multi_curl, $running);
		}
		while ($running);

		// All HTMLs downloaded. Now parse the data.
		foreach ($profileList as &$item) {
			$profile = &$item['profile'];
			$ch = &$item['curl'];
			$html = curl_multi_getcontent($ch);
			curl_multi_remove_handle($multi_curl, $ch);
			unset($item['curl']);
			$sc2parser->parseHTML($html, $profile);
			// Final adjustments.
			$profile['account']['clan'] = $this->get_clan_id($profile);
			unset($profile['clan']);
			foreach ($profile['1v1'] as $key => &$value) {
				if (array_key_exists($key, self::$indexOf)) {
					$value = self::$indexOf[$key][$value];
				}
			}
			$item = $profile;
		}

		curl_multi_close($multi_curl);

		return $profileList;
	}


	// Save the profiles list into the database.
	public function save_profiles (&$profileList) {
		$volatileFields = array ('portrait', '1v1');
		foreach ($profileList as &$profile) {
			$id = &$profile['id'];
			// The profile does not exists. Insert it.
			if ($id === null) {
				$this->database_insert ($profile, 'account');
				$id = $this->db->insert_id;
				foreach ($volatileFields as $field) {
					$profile[$field]['account'] = $id;
					$this->database_insert ($profile, $field);
				}
			}
			// Existing profile. Update it.
			else {
				$this->database_update ($profile, 'account');
				foreach ($volatileFields as $field) {
					$this->database_update ($profile, $field);
				}
			}
		}
	}

	// Do all the update procedures.
	public function update_profiles () {
		$profileList = $this->parse_profiles();
		$this->save_profiles($profileList);
	}

	// Get clan number.
	public function get_clan_id ($profile) {
		$clan = &$profile['clan'];
		$clanTag = $clan['tag'];
		if ($clanTag === null)
			return null;
		$clanName = $clan['name'];
		$clanID = &self::$indexOf['clan'][$clanTag];
		// If this clan is not in list.
		if (! isset($clanID)) {
			$this->database_insert($profile, 'clan');
			$clanID = $this->db->insert_id;
		}
		return $clanID;
	}

	public function get_account_id ($url) {
		if (array_key_exists($url, self::$indexOf['account']))
			return self::$indexOf['account'][$url];
		else
			return null;
	}

	public function database_insert (&$profile, $field) {
		$query = $this->database_insert_query ($profile, $field);
		return $this->db->query($query);
	}

	public function database_update (&$profile, $field) {
		$query = $this->database_update_query ($profile, $field);
		return $this->db->query($query);
	}

	public function database_insert_query (&$profile, $field) {
		$columns = implode(", ", array_keys($profile[$field]));
		$values = array_values($profile[$field]);
		foreach ($values as &$value) {
			if ($value === null) {
				$value = 'NULL';
			}
			else if (is_string($value)) {
				$value = "'$value'";
			}
		}
		$values = implode(", ", $values);
		$table = self::$tableOf[$field];
		$query = "INSERT INTO $table ($columns) VALUES ($values);";
		return $query;
	}

	public function database_update_query (&$profile, $field) {
		$set = array();
		foreach ($profile[$field] as $key => $value) {
			if ($value === null) {
				$value = 'NULL';
			}
			else if (is_string($value)) {
				$value = "'$value'";
			}
			$set[] = "$key = $value";
		}
		$set = implode(", ", $set);
		$account = $profile['id'];
		$table = self::$tableOf[$field];
		$query = "UPDATE $table SET $set WHERE account = $account;";
		return $query;
	}
}

// Initialize.
sc2dataManager::init();

?>